package com.study.sfd.medicine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.study.common.utils.PageResult;
import com.study.common.utils.Query;
import com.study.sfd.medicine.config.login.ThreadLocalUtil;
import com.study.sfd.medicine.dao.MedicineDao;
import com.study.common.entity.MedicineEntity;
import com.study.sfd.medicine.entity.MedicineImgEntity;
import com.study.sfd.medicine.entity.SpecificationImgEntity;
import com.study.sfd.medicine.service.MedicineImgsService;
import com.study.sfd.medicine.service.MedicineService;
import com.study.sfd.medicine.service.SpecificationImgService;
import com.study.common.vo.MedicineDetail;
import com.study.common.vo.MedicineWithCover;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service("medicineService")
public class MedicineServiceImpl extends ServiceImpl<MedicineDao, MedicineEntity> implements MedicineService {

  @Autowired
  MedicineImgsService medicineImgService;

  @Autowired
  SpecificationImgService specificationImgService;

  public PageResult queryPage(Map<String, Object> params, List<Integer> druggistIds)
  {
    if (druggistIds == null) {
      Map<String, Object> map = ThreadLocalUtil.get();
      Object druggistId = map.get("druggistId");
      druggistIds = new ArrayList<>();
      druggistIds.add((Integer) druggistId);
    }

    IPage<MedicineEntity> page = this.page(
            new Query<MedicineEntity>().getPage(params),
            new LambdaQueryWrapper<MedicineEntity>().in(MedicineEntity::getDruggistId, druggistIds)
    );
    return new PageResult(page);
  }

  @Override
  public PageResult queryPageWithCover(Map<String, Object> params, List<Integer> druggistIds)
  {
    PageResult pageResult = this.queryPage(params, druggistIds);

    List<MedicineWithCover> medicineWithCovers = pageResult.getRecords().stream().map(record -> {
      MedicineEntity medicineEntity = (MedicineEntity) record;
      MedicineWithCover medicineWithCover = new MedicineWithCover(medicineEntity);
      List<String> imgUrls = medicineImgService.getImgUrlsByMdcId(medicineEntity.getId());
      if (!imgUrls.isEmpty()) {
        medicineWithCover.setCover(imgUrls.get(0));
      }
      return medicineWithCover;
    }).collect(Collectors.toList());

    pageResult.setRecords(medicineWithCovers);
    return pageResult;
  }

  @Override
  public MedicineDetail getDetailById(Integer id) {
    MedicineDetail medicineWithImgs = new MedicineDetail();

    MedicineEntity medicine = this.getById(id);
    BeanUtils.copyProperties(medicine, medicineWithImgs);

    medicineWithImgs.setMedicineImgs(
            medicineImgService.getImgUrlsByMdcId(id)
    );
    medicineWithImgs.setSpecificationImgs(
            specificationImgService.getImgUrlsByMdcId(id)
    );
    return medicineWithImgs;
  }

  @Override
  @Transactional
  public void saveWithImgs(MedicineDetail medicineWithImgs)
  {
    Map<String, Object> map = ThreadLocalUtil.get();
    int druggistId = (int) map.get("druggistId");
    MedicineEntity medicine = new MedicineEntity();
    BeanUtils.copyProperties(medicineWithImgs, medicine);
    medicine.setDruggistId(druggistId);
    this.save(medicine);

    medicineWithImgs.setId(medicine.getId());
    saveOtherInfo(medicineWithImgs);
  }

  private void saveOtherInfo(MedicineDetail medicineWithImgs)
  {
    medicineImgService.saveBatch(medicineWithImgs);
    specificationImgService.saveBatch(medicineWithImgs);
  }

  @Override
  @Transactional
  public void updateWithImgsById(MedicineDetail medicineWithImgs)
  {
    MedicineEntity medicine = new MedicineEntity();
    BeanUtils.copyProperties(medicineWithImgs, medicine);
    this.updateById(medicine);

    removeOtherInfo(medicine.getId());
    saveOtherInfo(medicineWithImgs);
  }

  private void removeOtherInfo(Integer mdcId)
  {
    medicineImgService.lambdaUpdate()
            .eq(MedicineImgEntity::getMedicineId, mdcId)
            .remove();
    specificationImgService.lambdaUpdate()
            .eq(SpecificationImgEntity::getMedicineId, mdcId)
            .remove();
  }

  @Override
  @Transactional
  public void removeWithImgsByIds(List<Integer> ids) {
    for (Integer mdcId : ids) {
      // 根据 mdc id 删除
      removeOtherInfo(mdcId);
      this.removeById(mdcId);
    }
  }
}
